package com.terry.trace.plugin;

import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;


/**
 * trace拦截 配置类
 * @author TerryJiang
 */
@Configuration
public class TraceGlobalConfiguration {

    /**
     * 注意：@ConditionalOnClass需要作用在类上，否则当放于方法上，却没有对应的class，会报错
     */
    @ConditionalOnClass(name = "feign.RequestInterceptor")
    protected static class TraceFeignInterceptorAutoConfig {

        @Bean
        public TraceFeignInterceptor traceFeignInterceptor() {
            return new TraceFeignInterceptor();
        }
    }

    @ConditionalOnClass(name = "javax.servlet.Filter")
    protected static class FilterRegistrationBeanAutoConfig {

        @Bean(name = "traceFilterRegistrationBean")
        public FilterRegistrationBean<TraceServletFilter> traceFilterRegistrationBean(){
            FilterRegistrationBean<TraceServletFilter> bean = new FilterRegistrationBean<>();
            bean.setFilter(new TraceServletFilter());
            // order的数值越小，优先级越高
            bean.setOrder(0);
            // /*的作用：任何路径都能进过滤器
            bean.addUrlPatterns("/*");
            return bean;
        }
    }

    @ConditionalOnClass(name = "com.netflix.hystrix.strategy.concurrency.HystrixConcurrencyStrategy")
    protected static class TraceCallableHystrixConcurrencyStrategyAutoConfig {

        @Bean
        public ThreadLocalCallableHystrixConcurrencyStrategy threadLocalCallableHystrixConcurrencyStrategy() {
            return new ThreadLocalCallableHystrixConcurrencyStrategy();
        }
    }

    @ConditionalOnClass(name = "org.springframework.cloud.stream.annotation.StreamListener")
    protected static class SpringCloudStreamTraceAutoConfig {

        @Bean
        public SpringCloudStreamTraceConfig springCloudStreamTraceConfig() {
            return new SpringCloudStreamTraceConfig();
        }
    }
}
